package com.dldata.devtools30.controller.si;

/**
 * Created by ai on 2017/1/11.
 */


import cn.hutool.core.map.CaseInsensitiveMap;
import com.dldata.devtools30.controller.DevBase30Controller;
import com.dldata.devtools30.entity.*;
import com.dldata.devtools30.repository.metadata.DevtModelMetadataFieldDao;
import com.dldata.devtools30.repository.metadata.DevtModelMetadataTableDao;
import com.dldata.devtools30.repository.zhibiao.*;
import com.dldata.devtools30.utils.Public;
import com.dldata.devtools30.utils.StringUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**

 * 将请求的commonApi与管理的Controller分开
 */
@Controller
@RequestMapping(value = "/ZhibiaoSearchService")
@Slf4j
public class ZhibiaoSearchServiceController extends DevBase30Controller {
    
    @Autowired
    DevtZbplanItemEntityDao devtZbplanItemEntityDao;
    
    @Autowired
    DevtZbcfgInfoEntityDao devtZbcfgInfoEntityDao;
    
    @Autowired
    DevtZbobjInfoEntityDao devtZbobjInfoEntityDao;
    
    @Autowired
    DevtZbobjFieldEntityDao devtZbobjFieldEntityDao;
    
    @Autowired
    DevtZbplanZbobjEntityDao devtZbplanZbobjEntityDao;
    
    @Autowired
    DevtZbplanParatjEntityDao devtZbplanParatjEntityDao;
    
    @Autowired
    DevtModelMetadataTableDao devtModelMetadataTableDao;
    
    @Autowired
    DevtModelMetadataFieldDao devtModelMetadataFieldDao;
    
    /**
     * 1、根据指标确定模型
     * 2、根据模型和指标对象确定指定字段
     * 3、根据模型确定查询参数
     * @param request
     * @param res
     * @return
     */
    @RequestMapping(value = "")
    @ResponseBody
    public HashMap zhibiaoSearch(
            HttpServletRequest request, HttpServletResponse res,@RequestParam Map<String, String> paramMap) throws IOException {
        String p_plan_id = paramMap.get("p_plan_id");
        String p_zbobj_code = paramMap.get("p_zbobj_code");
        List<String> allSqlList=new ArrayList();
        
        try{
        
            //zbInfoMap 指标Map
            List<DevtZbcfgInfoEntity> zbcfgInfoEntityList = devtZbcfgInfoEntityDao.getAllByPlanId(p_plan_id);
            Map<String, List<DevtZbcfgInfoEntity>> zbInfoMap = zbcfgInfoEntityList.stream().collect(Collectors.groupingBy(DevtZbcfgInfoEntity::getModelid));
            Set<String> modelIdSet = zbInfoMap.keySet();
        
            //zbObjFieldMap 指标对象字段Map,并根据方案配置的序号排序
            List<DevtZbplanZbobjEntity> zbobjEntityList = devtZbplanZbobjEntityDao.getAllByPlanId(p_plan_id);
            if(!StringUtil.isEmptyOrLength0(p_zbobj_code)){
                List<String> pZbObjCodeList = Arrays.asList(p_zbobj_code.split(","));
                List<DevtZbplanZbobjEntity> zbobjEntityRemove=new ArrayList<>();
                for (int i = 0; i < zbobjEntityList.size(); i++) {
                    DevtZbplanZbobjEntity devtZbplanZbobjEntity = zbobjEntityList.get(i);
                    if(!pZbObjCodeList.contains(devtZbplanZbobjEntity.getZbobjcode())){
                        zbobjEntityRemove.add(devtZbplanZbobjEntity);
                    }
                }
                zbobjEntityList.removeAll(zbobjEntityRemove);
            }
            Map<String, List<DevtZbplanZbobjEntity>> zbPlanObjMap = zbobjEntityList.stream().collect(Collectors.groupingBy(DevtZbplanZbobjEntity::getZbobjid));
            Map<String, List<DevtZbobjFieldEntity>> zbObjFieldMap =new HashMap<>();
            for (Iterator<String> iterator = modelIdSet.iterator(); iterator.hasNext(); ) {
                String modelId = iterator.next();
                List<DevtZbobjFieldEntity> allByModelIdAndObjid = devtZbobjFieldEntityDao.getAllByModelIdAndObjid(modelId, zbPlanObjMap.keySet());
                allByModelIdAndObjid.sort(new Comparator<DevtZbobjFieldEntity>() {
                    @Override
                    public int compare(DevtZbobjFieldEntity o1, DevtZbobjFieldEntity o2) {
                        return zbPlanObjMap.get(o1.getZbobjid()).get(0).getXh().compareTo(zbPlanObjMap.get(o2.getZbobjid()).get(0).getXh());
                    }
                });
                zbObjFieldMap.put(modelId,allByModelIdAndObjid);
            }
        
            //weiDataList 将指标对象的数据构建成以代码为key,名称为value的map
            List<Map<String,String>> weiDataList=new ArrayList<>();
            List<DevtZbobjInfoEntity> zbobjInfoEntityList = devtZbobjInfoEntityDao.getAllByIdList(zbPlanObjMap.keySet());
            zbobjInfoEntityList.sort(new Comparator<DevtZbobjInfoEntity>() {
                @Override
                public int compare(DevtZbobjInfoEntity o1, DevtZbobjInfoEntity o2) {
                    return zbPlanObjMap.get(o1.getId()).get(0).getXh().compareTo(zbPlanObjMap.get(o2.getId()).get(0).getXh());
                }
            });
            for (int i = 0; i < zbobjInfoEntityList.size(); i++) {
                DevtZbobjInfoEntity devtZbobjInfoEntity = zbobjInfoEntityList.get(i);
                allSqlList.add(devtZbobjInfoEntity.getZbobjdatasql());
                List<Map<String, Object>> queryForList = jdbcTemplate.queryForList(devtZbobjInfoEntity.getZbobjdatasql());
                HashMap zbObjMap=new HashMap();
                for (int j = 0; j < queryForList.size(); j++) {
                    Map<String, Object> stringObjectMap = queryForList.get(j);
                    CaseInsensitiveMap caseInsensitiveMap=new CaseInsensitiveMap(stringObjectMap);
                    zbObjMap.put(caseInsensitiveMap.get("dm"),caseInsensitiveMap.get("mc"));
                }
                weiDataList.add(zbObjMap);
            }
        
            //zbParatjMap 查询条件Map
            List<DevtZbplanParatjEntity> zbplanParatjEntityList = devtZbplanParatjEntityDao.getAllByPlanid(p_plan_id);
            Map<String, List<DevtZbplanParatjEntity>> zbParatjMap
                    = zbplanParatjEntityList.stream().collect(Collectors.groupingBy(DevtZbplanParatjEntity::getModelid));
        
            //zbSqlMap 指标模型字段中文与字段映射
            List<DevtModelMetadataTableEntity> tableEntityList = devtModelMetadataTableDao.getAllByIdList(modelIdSet);
            Map<String, DevtModelMetadataTableEntity> modelTableMap
                    = tableEntityList.stream().collect(Collectors.toMap(DevtModelMetadataTableEntity::getId, v -> v));
            List<DevtModelMetadataFieldEntity> metadataFieldEntityList = devtModelMetadataFieldDao.getAllByTidList(modelIdSet);
            HashMap<String,String> zbSqlMap=new HashMap();
            metadataFieldEntityList.stream().forEach(
                    devtModelMetadataFieldEntity -> {
                        DevtModelMetadataTableEntity modelMetadataTableEntity = modelTableMap.get(devtModelMetadataFieldEntity.getFormId());
                        devtModelMetadataFieldEntity.getFormId();
                        String zhibiaokey="["+modelMetadataTableEntity.getName()+"."+devtModelMetadataFieldEntity.getFieldName()+"]";
                        String zhibiaovalue="["+modelMetadataTableEntity.getViewcode()+"].["+devtModelMetadataFieldEntity.getFieldCode()+"] ";
                        zbSqlMap.put(zhibiaokey,zhibiaovalue);
                }
            );
            //sqlList 组装SQL，一个模型表一个SQL
            List<String> sqlList=new ArrayList<>();
            List<String> wFieldList=new ArrayList<>();
            for (Iterator<String> iterator = modelIdSet.iterator(); iterator.hasNext(); ) {
                String modelId = iterator.next();
                List<DevtZbcfgInfoEntity> devtZbcfgInfoEntities = zbInfoMap.get(modelId);
                //指标段
                StringBuilder zbsqlBuilder=new StringBuilder();
                for (int i = 0; i < devtZbcfgInfoEntities.size(); i++) {
                    DevtZbcfgInfoEntity devtZbcfgInfoEntity = devtZbcfgInfoEntities.get(i);
        
                    Pattern pattern = Pattern.compile(Public.REG_FIELD_ZH);
                    Matcher matcher=pattern.matcher(devtZbcfgInfoEntity.getZbsql());
                    matcher.find();
                    String groupValues = matcher.group(0);
                    String zbsql=devtZbcfgInfoEntity.getZbsql().replace(groupValues," cast(" + zbSqlMap.get(groupValues)+" as decimal(28,"+devtZbcfgInfoEntity.getXsws()+")) ");
                    zbsqlBuilder.append(zbsql).append(" ").append(devtZbcfgInfoEntity.getZbcode()).append(",");
                }
                zbsqlBuilder.deleteCharAt(zbsqlBuilder.length()-1);
        
                //指标对象模型段
                List<DevtZbobjFieldEntity> devtZbobjFieldEntities = zbObjFieldMap.get(modelId);
                StringBuilder zbobjgroupby=new StringBuilder();
                StringBuilder zbobjselect=new StringBuilder();
                for (int i = 0; i < devtZbobjFieldEntities.size(); i++) {
                    DevtZbobjFieldEntity devtZbobjFieldEntity = devtZbobjFieldEntities.get(i);
                    zbobjgroupby.append(devtZbobjFieldEntity.getModelfieldcode()).append(",");
                    zbobjselect.append(devtZbobjFieldEntity.getModelfieldcode()).append(" wcloumn").append(i).append(",");
                    if(!wFieldList.contains("wcloumn"+i)){
                        wFieldList.add("wcloumn"+i);
                    }
                }
                zbobjgroupby.deleteCharAt(zbobjgroupby.length()-1);
                zbobjselect.deleteCharAt(zbobjselect.length()-1);
        
                //where 查询条件段
                List<DevtZbplanParatjEntity> paratjEntityList =zbParatjMap.containsKey(modelId)?zbParatjMap.get(modelId):new ArrayList<>();
                StringBuilder cxTjSqlBuilder=new StringBuilder();
                for (int i = 0; i < paratjEntityList.size(); i++) {
                    DevtZbplanParatjEntity devtZbplanParatjEntity = paratjEntityList.get(i);
                    String csValue = paramMap.get(devtZbplanParatjEntity.getParaname());
                    csValue= StringUtil.isEmptyOrLength0(csValue)?"":csValue;
                    cxTjSqlBuilder.append(devtZbplanParatjEntity.getTjsql().replace("#values#",csValue));
                }
                
                StringBuilder destSql=new StringBuilder();
                destSql.append(" select ");
                destSql.append(zbobjselect).append(",").append(zbsqlBuilder);
                destSql.append(" from ").append(modelTableMap.get(modelId).getViewcode());
                destSql.append(" where 1=1 ").append(cxTjSqlBuilder);
                destSql.append(" group by ").append(zbobjgroupby);
                
                sqlList.add(destSql.toString());
            }
            
            //只是获取执行SQL语句
            if(Boolean.TRUE.toString().equalsIgnoreCase(paramMap.get("p_test_sql"))){
                allSqlList.addAll(sqlList);
                HashMap resultMap= new HashMap();
                resultMap.put("success",Boolean.TRUE);
                resultMap.put("msg","查询成功");
                resultMap.put("data", allSqlList);
                return resultMap;
            }
        
            //执行查询SQL并组装数据
            HashMap<String,Map<String, Object>> destDataHashMap =new HashMap<>();
            for (int i = 0; i < sqlList.size(); i++) {
                String sql = sqlList.get(i);
                List<Map<String, Object>> queryForList = jdbcTemplate.queryForList(sql);
                log.info("sql:: "+sql);
                for (int j = 0; j < queryForList.size(); j++) {
                    Map<String, Object> searchDataMap = queryForList.get(j);
                    StringBuilder destFieldKey=new StringBuilder();
                    for (int k = 0; k < wFieldList.size(); k++) {
                        String fieldKey = wFieldList.get(k);
                        Object weiObjOne = searchDataMap.get(fieldKey);
                        destFieldKey.append(weiObjOne==null?"":weiObjOne.toString()).append(";;;");
                    }
                    Map<String, Object> destDataMapOne = destDataHashMap.get(destFieldKey.toString());
                    if(destDataMapOne==null){
                        destDataMapOne=new LinkedHashMap<>();
                        //设置维默认值维空串
                        for (int k = 0; k < wFieldList.size(); k++) {
                            String wfieldname = wFieldList.get(k);
                            destDataMapOne.put(wfieldname,"");
                        }
                        //设置指标默认值维空串
                        for (int k = 0; k < zbcfgInfoEntityList.size(); k++) {
                            DevtZbcfgInfoEntity devtZbcfgInfoEntity = zbcfgInfoEntityList.get(k);
                            destDataMapOne.put(devtZbcfgInfoEntity.getZbcode(),"");
                        }
                    }
                    destDataMapOne.putAll(searchDataMap);
                    destDataHashMap.put(destFieldKey.toString(),destDataMapOne);
                }
            }
            
            //将维代码转为维名称
            Collection<Map<String, Object>> mapCollection = destDataHashMap.values();
            for (Iterator<Map<String, Object>> iterator = mapCollection.iterator(); iterator.hasNext(); ) {
                Map<String, Object> objectMap = iterator.next();
                for (int i = 0; i < wFieldList.size(); i++) {
                    String wfieldname = wFieldList.get(i);
                    Object wDmValue = objectMap.get(wfieldname);
                    String wmcValue = weiDataList.get(i).get(wDmValue);
                    wmcValue=StringUtil.isEmptyOrLength0(wmcValue)?(StringUtil.isEmptyOrLength0(wDmValue)?"":wDmValue.toString()):wmcValue;
                    objectMap.put(wfieldname,wmcValue);
                }
            }
            
            HashMap resultMap= new HashMap();
            resultMap.put("success",Boolean.TRUE);
            resultMap.put("msg","查询成功");
            resultMap.put("data", mapCollection);
            
            return resultMap;
    
    
        }catch (Throwable throwable){
            log.error(throwable.getMessage(),throwable);
    
            StringWriter stringWriter = new StringWriter();
            throwable.printStackTrace(new PrintWriter(stringWriter));
            HashMap resultMap= new HashMap();
            resultMap.put("success",Boolean.FALSE);
            resultMap.put("msg","执行失败");
            resultMap.put("data", stringWriter.toString());
            return resultMap;
        }
    }

}

